import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.registry.*;
import java.util.Hashtable;
import java.net.*;

public class Client extends UnicastRemoteObject implements Client_itf {
	
	//attributs
	private static Server_itf monServeur;
	private static String machineServeur = "localhost";
	private static int port = 1099;
	private static String nomServeur = "monserveur";
	private static Client_itf monClient;
	
	//cf tp ticket launcherImpl
	private static Hashtable<Integer,SharedObject> sharedObjects = new Hashtable();
	
	public Client() throws RemoteException {
		super();
	}


///////////////////////////////////////////////////
//         Interface to be used by applications
///////////////////////////////////////////////////

	// initialization of the client layer
	public static void init() {
		//recupérer le serveur remote
		try {
			monServeur = (Server_itf)Naming.lookup("//"+machineServeur+":"+port+"/"+nomServeur);
			monClient= new Client();
			
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NotBoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	// lookup in the name server
	public static SharedObject lookup(String name) {
		try{//si on ne trouve pas l'élément, il faut le rajouter
			int id1 = monServeur.lookup(name);
			System.out.println(id1);
			if(id1==0){
				return null;
			}
			else{
				SharedObject so = sharedObjects.get(id1);
				return so;
			}
		}
		catch(RemoteException e){
			e.printStackTrace();
			return null;
		}
	}		
	
	// binding in the name server
	public static void register(String name, SharedObject_itf so) {
		try{
			int id = so.getId();
			//niveau serveur
			monServeur.register(name,id);
			
		}
		catch(RemoteException e){
			e.printStackTrace();
		}
	}

	// creation of a shared object
	public static SharedObject create(Object o) {
		try{int id_object = monServeur.create(o);
			SharedObject so = new SharedObject(id_object,o);
			sharedObjects.put(id_object,so);
			
			monServeur.create(o);
			
			return so;}
		catch(RemoteException e){
			e.printStackTrace();
		}
		//à voir
		return null;
	}
	
/////////////////////////////////////////////////////////////
//    Interface to be used by the consistency protocol
////////////////////////////////////////////////////////////

	// request a read lock from the server
	public static Object lock_read(int id) {
		try {
			return monServeur.lock_read(id,monClient);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

	// request a write lock from the server
	public static Object lock_write (int id) {
		try {
			return monServeur.lock_write(id,monClient);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

	// receive a lock reduction request from the server
	public Object reduce_lock(int id) throws java.rmi.RemoteException {
		return null;
	}


	// receive a reader invalidation request from the server
	public void invalidate_reader(int id) throws java.rmi.RemoteException {
	}


	// receive a writer invalidation request from the server
	public Object invalidate_writer(int id) throws java.rmi.RemoteException {
		return null;
	}
}
